#include "Device/Zigbee3Device.h"

Zigbee3Device::Zigbee3Device(QObject *parent) :
    BaseInterface<Zigbee3Device>(parent)
{

    qDebug()<<"zigbee3 running-1";
    m_pInstance = this;
    pointProtocol = new PointProtocol(this);
    zigbeeConfigProtocol = new ZigbeeConfigProtocol(this);
    zigbeeControlProtocol = new ZigbeeControlProtocol(this);
    zigbeeNewControlProtocol = new ZigbeeNewControlProtocol(this);



    this->registerProtocol(pointProtocol);
    this->registerProtocol(zigbeeConfigProtocol);
    this->registerProtocol(zigbeeControlProtocol);
    this->registerProtocol(zigbeeNewControlProtocol);

    registerFuncHandler(ControlPointFunc::FunctionCode, &Zigbee3Device::controlPointFuncHandle);
    registerCmdHandler(Zigbee3BackQueryCmd::FunctionCode,Zigbee3BackQueryCmd::staticMetaObject, &Zigbee3Device::zigbee3QueryBackDataHandle);
    registerCmdHandler(Zigbee3NewJoinParamCmd::FunctionCode,Zigbee3NewJoinParamCmd::staticMetaObject, &Zigbee3Device::Zigbee3NewJoinParamCmdHandle);
    registerCmdHandler(Zigbee3AcceptDataCmd::FunctionCode,Zigbee3AcceptDataCmd::staticMetaObject, &Zigbee3Device::zigbee3DataHandle);
    registerCmdHandler(Zigbee3QuitBackCmd::FunctionCode,Zigbee3QuitBackCmd::staticMetaObject, &Zigbee3Device::Zigbee3QuitBackCmdHandle);
    registerCmdHandler(Zigbee3QueryVersionCmd::FunctionCode,Zigbee3QueryVersionCmd::staticMetaObject, &Zigbee3Device::Zigbee3QuitVersionCmdHandle);
    qDebug()<<"zigbee3 running-2";
}

void Zigbee3Device::controlPointFuncHandle(QSharedPointer<BaseFunc> sharedFunc)
{
    ControlPointFunc *pointControlFunc = qobject_cast<ControlPointFunc*>(sharedFunc.data());
    QList<ControlPointStruct> controlPointList;
    qDebug()<<"zigbee3 controlpointhandle!";
    if(pointControlFunc->sourceDevice() == this->name())
    {
        controlPointList.append(pointControlFunc->sourcePointList());
     //   controlPointList.append(pointControlFunc->controlPointList());
       //qDebug()<<pointControlFunc->sourceDevice();
        //qDebug()<<"name="<<this->name();
    }
    else
    {
        //qDebug()<<"else now";
        //qDebug()<<pointControlFunc->sourceDevice();
         //qDebug()<<"name"<<this->name();
   //     controlPointList.append(pointControlFunc->sourcePointList());
        controlPointList.append(pointControlFunc->controlPointList());
    }
    if(controlPointList.isEmpty())
    {
       qDebug()<<"return";
        return;
    }
    Zigbee3ListXml *zigbee3ListXml = Zigbee3ListXml::getInstance();
    if((zigbee3ListXml->ZigbeeVersion().toHex().toInt(0,16))==0x05)
    {

       // qDebug()<<"Not right Version";
        return;
    }
    QList<Zigbee3Struct> zigbee3List = zigbee3ListXml->zigbeeList(controlPointList);
    foreach(const Zigbee3Struct &zigbee,zigbee3List)
    {
        qDebug()<<"zigbee3.0";
        Zigbee3ControlPointListCmd *zigbee3SendCmd = new Zigbee3ControlPointListCmd();
        zigbee3SendCmd->setZigbee(zigbee);

        PortStruct target;
        foreach (const BasePort *port , m_portList)
        {
             if((port->portParam().type() == "UART" && port->portParam().name() == "Zigbee"))
             {
                 target = port->portParam();
         //        qDebug()<<"port right="<<port->portParam().type();
             }
        }

       emit sendDataSignal(target,zigbee3SendCmd->toPackage().body());
    }

}

void Zigbee3Device::Zigbee3NewJoinParamCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(source);
    Zigbee3NewJoinParamCmd *setControlPointCmd = qobject_cast<Zigbee3NewJoinParamCmd*>(sharedCmd.data());
    Zigbee3Struct zigbeeStruck;
    Zigbee3ListXml *zigbee3ListXml = Zigbee3ListXml::getInstance();

    zigbeeStruck.setMac(setControlPointCmd->Mac());
    zigbeeStruck.setNwk(setControlPointCmd->Nwk());
    QByteArray data;
    data.clear();
    data.append(setControlPointCmd->Nwk());
    data.append(setControlPointCmd->Mac());
    qDebug()<<"new join try";
   if(zigbee3ListXml->modify(1,zigbeeStruck)==true)
    {
    PortStruct target;
    foreach (const BasePort *port , m_portList)
    {
         if((port->portParam().type() == "UART" && port->portParam().name() == "RS485"))
         {
             target = port->portParam();
         }
    }
    emit sendDataSignal(target,data);

    LogicCloudDataFunc *logicCloudDataFunc=new  LogicCloudDataFunc();
    logicCloudDataFunc->setData(data);
    logicCloudDataFunc->setDataFunctionCode(0x46);
    logicCloudDataFunc->setSourceDevice(this->name());
    QSharedPointer<BaseFunc> sharedlogicCloudDataFuncFunc(logicCloudDataFunc);
    emit transferFuncSignal(sharedlogicCloudDataFuncFunc);

    qDebug()<<"join zigbee3 now";
    }
}

void Zigbee3Device::zigbee3QueryBackDataHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(source);
    qDebug()<<"backdatanow";
    Zigbee3BackQueryCmd *zigbeeQueryBackData = qobject_cast<Zigbee3BackQueryCmd*>(sharedCmd.data());
    LogicCloudDataFunc *logicCloudDataFunc=new  LogicCloudDataFunc();
    logicCloudDataFunc->setData(zigbeeQueryBackData->Zigbee3BackQueryData());
    logicCloudDataFunc->setDataFunctionCode(0x45);
    logicCloudDataFunc->setSourceDevice(this->name());
    QSharedPointer<BaseFunc> sharedlogicCloudDataFuncFunc(logicCloudDataFunc);
    emit transferFuncSignal(sharedlogicCloudDataFuncFunc);
    PortStruct target;
    foreach (const BasePort *port , m_portList)
    {

         if((port->portParam().type() == "UART" && port->portParam().name() == "RS485"))
         {
             target = port->portParam();
         }
    }
    emit sendDataSignal(target,zigbeeQueryBackData->Zigbee3BackQueryData());

    //  PortStruct target1;
  // target1.setType("UDP");
 //   target1.setName("NetPointDeviceUDP");
 //   target1.setIp("255.255.255.255");
 //   target1.setPort(20000);
 //   qDebug()<<"backdatanow2";
 //   QByteArray UdpBackQueryData;
 //   UDP udp;
 //   udp.write(target1,zigbeeQueryBackData->Zigbee3BackQueryData());
   //  emit sendDataSignal(target1,zigbeeQueryBackData->Zigbee3BackQueryData());
}

void Zigbee3Device::Zigbee3QuitBackCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
     Q_UNUSED(source);
     Zigbee3QuitBackCmd *zigbee3QuitBackCmd = qobject_cast<Zigbee3QuitBackCmd*>(sharedCmd.data());
     qDebug()<<"QuitBack now;";
     QByteArray Data;
     Data.append(zigbee3QuitBackCmd->Nwk());
     Data.append(0x01);
     LogicCloudDataFunc *logicCloudDataFunc=new  LogicCloudDataFunc();
     logicCloudDataFunc->setData(Data);
     logicCloudDataFunc->setDataFunctionCode(0x43);
     logicCloudDataFunc->setSourceDevice(this->name());
     QSharedPointer<BaseFunc> sharedlogicCloudDataFuncFunc(logicCloudDataFunc);
     emit transferFuncSignal(sharedlogicCloudDataFuncFunc);
}

void Zigbee3Device::zigbee3DataHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(source);
    qDebug()<<"running zigbee3DataHandle/";
    Zigbee3ListXml *zigbee3ListXml = Zigbee3ListXml::getInstance();
    if(zigbee3ListXml->ZigbeeVersion().toHex().toInt(0,16)==5)
    {
        return ;
    }
    Zigbee3AcceptDataCmd *zigbeeData = qobject_cast<Zigbee3AcceptDataCmd*>(sharedCmd.data());
    QByteArray nwk=zigbeeData->nwk();
    QList<Zigbee3Struct>zigbee3List=zigbee3ListXml->zigbee3List();
    quint16 yhdata=zigbeeData->yhData()&0x01;
    qDebug()<<"-=-=-=-=-=-=----zbyhdata="<<QString::number(zigbeeData->yhData());
    qDebug()<<"-=-=-=-=-=-=----zbyhdata="<<QString::number(yhdata);
    foreach(const Zigbee3Struct &zigbee3Struct,zigbee3List)
    {
     //   qDebug()<<"A";
        if(zigbee3Struct.nwk()==nwk)
        {
            qDebug()<<"clusterID="<<zigbeeData->clusterID();
            switch(zigbeeData->clusterID())
            {
            case 0x05:

                if(zigbee3Struct.type()==0x01||zigbee3Struct.type()==0x04 )
                {
                    foreach(ControlPointStruct pointStruct,zigbee3Struct.pointList())
                    {
                        quint16 address;
                        quint16 value=0;
                        quint16 coreData;
                        address=pointStruct.address();
                        coreData=zigbeeData->coreData().toUInt(0,16);
                    //    qDebug()<<zigbeeData->coreData();
                    //    qDebug()<<"coreData="<<coreData;
                        qDebug()<<"coreData="<<QString::number(coreData);
                        switch(coreData)
                        {

                            case 0x01:value=0x01;break;
                            case 0x00:value=0x00;break;
                            default:return ;
                        }
                        ControlPointFunc *pointControlFunc = new ControlPointFunc();
                        ControlPointStruct sourcePoint;
                        sourcePoint.setAddress(address);
                        sourcePoint.setValue(value);
                        QList<ControlPointStruct> sourcePointList;
                        sourcePointList.append(sourcePoint);
                        pointControlFunc->setSourceDevice(this->name());
                        pointControlFunc->setSourcePointList(sourcePointList);

                        QSharedPointer<BaseFunc> sharedPointControlFunc(pointControlFunc);
                        emit transferFuncSignal(sharedPointControlFunc);
                    }
                }
                if(zigbee3Struct.type()==0x03)
                {
                    qDebug()<<"type====03---------------------------------";
                    foreach(ControlPointStruct pointStruct,zigbee3Struct.pointList())
                    {
                        QDateTime current_time = QDateTime::currentDateTime();
                        quint16 address;
                        quint16 value=0;
                        quint16 coreData;
                        quint16 opendata;

                        int triggertime=current_time.toTime_t();
                        address=pointStruct.address();
                        coreData=zigbeeData->coreData().toInt(0,16);
                         opendata=coreData&0x01;
                         qDebug()<<"coreData="<<QString::number(coreData);
                        qDebug()<<"opendata="<<QString::number(opendata);
                    //    qDebug()<<zigbeeData->coreData();
                    //    qDebug()<<"coreData="<<coreData;
                    if(yhdata==1)
                    {
                        switch(opendata)
                        {
                            case 0x01:value=0x01;
                            qDebug()<<" now we know ----------------------0x0100";
                            if(zigbee3ListXml->onTriggerTime.contains(address))
                            {
                                //qDebug()<<"triggertime="<<triggertime;

                                int getTime=zigbee3ListXml->onTriggerTime.value(address);
                                //qDebug()<<"gettime="<<getTime;
                                if((triggertime-getTime)<5)
                                {
                                    qDebug()<<"this time is too short";
                                        return ;
                                }
                            }
                            zigbee3ListXml->onTriggerTime.insert(address,triggertime);
                            break;
                            case 0x00:value=0x00;
                            qDebug()<<" now we know ----------------------0x000";
                            //qDebug()<<"address=="<<address;
                            if(zigbee3ListXml->offTriggerTime.contains(address))
                            {
                                ///qDebug()<<"triggertime="<<triggertime;

                                int getTime=zigbee3ListXml->offTriggerTime.value(address);
                                qDebug()<<"gettime="<<getTime;
                                if((triggertime-getTime)<2)
                                {
                                //    qDebug()<<"this time is too short";
                                        return ;
                                }

                            }zigbee3ListXml->offTriggerTime.insert(address,triggertime);
                            break;

                        default://qDebug()<<"now coreData=="<<coreData;
                                    return;break;
                        }

                    }
                    else
                    {
                        return;
                    }
                        ControlPointFunc *pointControlFunc = new ControlPointFunc();
                        ControlPointStruct sourcePoint;
                        sourcePoint.setAddress(address);
                        sourcePoint.setValue(value);
                        QList<ControlPointStruct> sourcePointList;
                        sourcePointList.append(sourcePoint);
                        pointControlFunc->setSourceDevice(this->name());
                        pointControlFunc->setSourcePointList(sourcePointList);
                        QSharedPointer<BaseFunc> sharedPointControlFunc(pointControlFunc);
                        emit transferFuncSignal(sharedPointControlFunc);
                    }
                }
                break;
            case 0x00:
                if(zigbee3Struct.type()==0x06)
                {
                    qDebug()<<"type=06";
                    quint16 clusterID=0;
                    clusterID=zigbeeData->Body().mid(11,2).toHex().toInt(0,16);
                    Zigbee3InfraredXml *zigbee3InfraredXml = Zigbee3InfraredXml::getInstance();
                    qDebug()<<"clusterid="<<clusterID;
                    if(clusterID==0x0c41)
                    {
                        qDebug()<<"ID is right";
                        quint8 datalengh=zigbeeData->Body().mid(14,1).toHex().toInt(0,16);
                        QByteArray InfraredData=zigbeeData->Body().mid(15,datalengh);
                        quint8 InfraredOrder=InfraredData.mid(4,1).toHex().toInt(0,16);
                        qDebug()<<"data="<<DataTypeConver::formatString(InfraredData);
                        qDebug()<<"dataOrder="<<DataTypeConver::formatString(InfraredData.mid(4,1));
                        switch(InfraredOrder)
                        {
                            case 0xdf:qDebug()<<"Order is df";
                                      QByteArray InfraredID=InfraredData.mid(7,16);
                                      Zigbee3InfraredStruct zigbee3InfraredStruct;
                                      quint16 pointValue=((InfraredID.mid(14,1).toHex().toInt(0,16))-1)*256+((InfraredID.mid(15,1).toHex().toInt(0,16))-1);
                                      qDebug()<<"addr="<<DataTypeConver::formatString(InfraredID.mid(14,2));
                                      zigbee3InfraredStruct.m_mac=zigbee3Struct.mac();
                                      zigbee3InfraredStruct.m_nwk=zigbee3Struct.nwk();
                                      zigbee3InfraredStruct.m_PointValue=pointValue;
                                      zigbee3InfraredStruct.m_data=InfraredID;
                                      zigbee3InfraredXml->CopyInfrared.insert(pointValue,zigbee3InfraredStruct);
                                      QString valuedata=QString("%1").arg(pointValue,4,16,QLatin1Char('0'));
                                      QByteArray data;
                                      data.clear();
                                     qDebug()<<"nwk="<<DataTypeConver::formatString(zigbee3InfraredStruct.m_nwk);
                                       qDebug()<<"addr="<<zigbee3InfraredStruct.m_PointValue;
                                     //  QString value=QString::number(zigbee3InfraredStruct.m_PointValue);
                                      data.append(zigbee3InfraredStruct.m_nwk);

                                      data.append(valuedata);

                                      LogicCloudDataFunc *logicCloudDataFunc=new  LogicCloudDataFunc();
                                      logicCloudDataFunc->setData(data);
                                      logicCloudDataFunc->setDataFunctionCode(0x5b);
                                      logicCloudDataFunc->setSourceDevice(this->name());
                                      QSharedPointer<BaseFunc> sharedlogicCloudDataFuncFunc(logicCloudDataFunc);
                                      emit transferFuncSignal(sharedlogicCloudDataFuncFunc);
                                      qDebug()<<"succer to learn";
                                //      emit transferFuncSignal(sharedlogicCloudDataFuncFunc);

                            ;break;
                        }
                    }
                }
            }
        }
    }

   // Zigbee3AcceptDataCmd a;
}

void Zigbee3Device::Zigbee3QuitVersionCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(source);
    qDebug()<<"Get Zigbee3VerSion data";
    Zigbee3QueryVersionCmd *zigbee3QueryVersionCmd=qobject_cast<Zigbee3QueryVersionCmd*>(sharedCmd.data());
    Zigbee3ListXml *zigbee3ListXml = Zigbee3ListXml::getInstance();

    QByteArray VersionData=zigbee3QueryVersionCmd->zigbeeQueryBackData();
    qDebug()<<"VersionData="<<VersionData.toHex().toInt(0,10);
    zigbee3ListXml->SetZigbeeVersion(VersionData);
    qDebug()<<"Zigbee3Ver="<<zigbee3ListXml->ZigbeeVersion().toHex().toInt(0,10);
}
